home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / apps / database / ingres04.lzh / source / qrymod / util.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-01-18  |  7.7 KB  |  369 lines

  1. # include    <ingres.h>
  2. # include    <aux.h>
  3. # include    <symbol.h>
  4. # include    <tree.h>
  5. # include    "qrymod.h"
  6.  
  7. /*
  8. **  TRIMQLEND -- trim QLEND node off of qualification
  9. **
  10. **    The QLEND node, and possible the AND node preceeding it,
  11. **    are trimmed off.  The result of this routine should be
  12. **    a very ordinary tree like you might see in some textbook.
  13. **
  14. **    A fast not on the algorithm: the pointer 't' points to the
  15. **    current node (the one which we are checking for a QLEND).
  16. **    's' points to 't's parent, and 'r' points to 's's parent;
  17. **    'r' is NULL at the top of the tree.
  18. **
  19. **    This routine works correctly on trees with no QLEND in
  20. **    the first place, returning the original tree.
  21. **
  22. **    If there is a QLEND, it must be on the far right branch
  23. **    of the tree, that is, the tree must be INGRES-canonical.
  24. **
  25. **    Parameters:
  26. **        qual -- the qualification to be trimmed.
  27. **
  28. **    Returns:
  29. **        A pointer to the new qualification.
  30. **        NULL if the qualification was null once the
  31. **            QLEND is stripped.
  32. **
  33. **    Side Effects:
  34. **        The tree pointed to by 'qual' may be modified.
  35. **
  36. **    Trace Flags:
  37. **        none
  38. */
  39.  
  40. QTREE *
  41. trimqlend(qual)
  42. QTREE    *qual;
  43. {
  44.     register QTREE    *t;
  45.     register QTREE    *s;
  46.     register QTREE    *r;
  47.  
  48.     t = qual;
  49.  
  50.     /* check for the simple null qualification case */
  51.     if (t == NULL || t->sym.type == QLEND)
  52.         return (NULL);
  53.     
  54.     /* scan tree for QLEND node */
  55.     for (r = NULL, s = t; (t = t->right) != NULL; r = s, s = t)
  56.     {
  57.         if (t->sym.type == QLEND)
  58.         {
  59.             /* trim of QLEND and AND node */
  60.             if (r == NULL)
  61.             {
  62.                 /* only one AND -- return its operand */
  63.                 return (s->left);
  64.             }
  65.  
  66.             r->right = s->left;
  67.             break;
  68.         }
  69.     }
  70.  
  71.     /* return tree with final AND node and QLEND node pruned */
  72.     return (qual);
  73. }
  74. /*
  75. **  APPQUAL -- append qualification to tree
  76. **
  77. **    The qualification is conjoined to the qualificaion of the
  78. **    tree which is passed.
  79. **
  80. **    Parameters:
  81. **        qual -- a pointer to the qualification to be appended.
  82. **        root -- a pointer to the tree to be appended to.
  83. **
  84. **    Returns:
  85. **        none
  86. **
  87. **    Side Effects:
  88. **        Both 'qual' ad 'root' may be modified.  Note that
  89. **            'qual' is linked into 'root', and must be
  90. **            retained.
  91. **
  92. **    Trace Flags:
  93. **        13
  94. */
  95.  
  96. appqual(qual, root)
  97. QTREE    *qual;
  98. QTREE    *root;
  99. {
  100.     register QTREE    *p;
  101.     register QTREE    *r;
  102.  
  103.     r = root;
  104. #    ifdef xQTR3
  105.     if (r == NULL)
  106.         syserr("appqual: NULL root");
  107. #    endif
  108.  
  109.     /*
  110.     **  Find node before QLEND node
  111.     **    p points the node we are examining, r points to
  112.     **    it's parent.
  113.     */
  114.  
  115.     while ((p = r->right) != NULL && p->sym.type != QLEND)
  116.     {
  117. #        ifdef xQTR3
  118.         if (p->sym.type != AND)
  119.             syserr("appqual: node %d", p->sym.type);
  120. #        endif
  121.         r = p;
  122.     }
  123.     
  124.     /* link in qualification */
  125.     r->right = qual;
  126. }
  127. /*
  128. **  QMERROR -- issue fatal error message and abort query
  129. **
  130. **    This call is almost exactly like 'error' (which is called),
  131. **    but never returns: the return is done by 'reset'.  Also, the
  132. **    R_up pipe is flushed.
  133. **
  134. **    Parameters:
  135. **        errno -- the error number.
  136. **        qmode -- the query mode to pass as $0, -1 if none.
  137. **        vn -- the varno of the relation name to pass as
  138. **            $1, -1 if none.
  139. **        p1 to p5 -- the parameters $2 through $6
  140. **
  141. **    Returns:
  142. **        non-local (via reset())
  143. **
  144. **    Side Effects:
  145. **        The error message is generated.
  146. **
  147. **    Trace Flags:
  148. **        none
  149. */
  150.  
  151. char *QmdName[] =
  152. {
  153.     "[ERROR]",    /* 0 = mdRETTERM */
  154.     "RETRIEVE",    /* 1 = mdRETR */
  155.     "APPEND",    /* 2 = mdAPP */
  156.     "REPLACE",    /* 3 = mdREPL */
  157.     "DELETE",    /* 4 = mdDEL */
  158.     "",        /* 5 = mdCOPY */
  159.     "",        /* 6 = mdCREATE */
  160.     "",        /* 7 = mdDESTROY */
  161.     "",        /* 8 = mdHELP */
  162.     "",        /* 9 = mdINDEX */
  163.     "",        /* 10 = mdMODIFY */
  164.     "",        /* 11 = mdPRINT */
  165.     "",        /* 12 = mdRANGE */
  166.     "",        /* 13 = mdSAVE */
  167.     "DEFINE",    /* 14 = mdDEFINE */
  168.     "RET_UNIQUE",    /* 15 = mdRET_UNI */
  169.     "",        /* 16 = mdVIEW */
  170.     "",        /* 17 = mdUPDATE */
  171.     "",        /* 18 = mdRESETREL */
  172.     "",        /* 19 = mdERIC */
  173.     "",        /* 20 = mdNETQRY */
  174.     "",        /* 21 = mdMOVEREL */
  175.     "",        /* 22 = mdPROT */
  176.     "",        /* 23 = mdINTEG */
  177.     "",        /* 24 = mdDCREATE */
  178. };
  179.  
  180.  
  181. qmerror(errno, qmode, vn, p1, p2, p3, p4, p5, p6)
  182. int    errno;
  183. int    qmode;
  184. int    vn;
  185. char    *p1, *p2, *p3, *p4, *p5, *p6;
  186. {
  187.     register char        *x1;
  188.     register char        *x2;
  189.     char            xbuf[MAXNAME + 1];
  190.     register int        i;
  191.     extern char        *trim_relname();
  192.  
  193.     /* set up qmode and varno parameters */
  194.     x1 = x2 = "";
  195.     i = qmode;
  196.     if (i >= 0)
  197.         x1 = QmdName[i];
  198.     i = vn;
  199.     if (i >= 0)
  200.         smove(trim_relname(Qt.qt_rangev[i].rngvdesc->reldum.relid),
  201.               x2 = xbuf);
  202.  
  203.     /* issue the error message and exit */
  204.     error(errno, x1, x2, p1, p2, p3, p4, p5, p6, 0);
  205.     syserr("qmerror");
  206. }
  207. /*
  208. **  LSETBIT -- set a bit in a domain set
  209. **
  210. **    Parameters:
  211. **        bitno -- the bit number to set (0 -> 127)
  212. **        xset -- the set to set it in.
  213. **
  214. **    Returns:
  215. **        none
  216. **
  217. **    Side Effects:
  218. **        none
  219. */
  220.  
  221. lsetbit(bitno, xset)
  222. int    bitno;
  223. long    xset[4];
  224. {
  225.     register int    b;
  226.     register int    n;
  227.     register int    *x;
  228.  
  229.     x = xset;
  230.  
  231.     b = bitno;
  232.     n = b >> LOG2WORDSIZE;
  233.     b &= WORDSIZE - 1;
  234.  
  235.     x[n] |= 1 << b;
  236. }
  237. /*
  238. **  MERGEVAR -- merge variable numbers to link terms
  239. **
  240. **    One specified variable gets mapped into another, effectively
  241. **    merging those two variables.  This is used for protection
  242. **    and integrity, since the constraint read from the tree
  243. **    must coincide with one of the variables in the query tree.
  244. **
  245. **    Parameters:
  246. **        va -- the variable which will dissappear.
  247. **        vb -- the variable which 'va' gets mapped into.
  248. **        root -- the root of the tree to map.
  249. **
  250. **    Returns:
  251. **        none
  252. **
  253. **    Side Effects:
  254. **        The tree pointed at by 'root' gets VAR and RESDOM
  255. **            nodes mapped.
  256. **        Range table entry for 'va' is deallocated.
  257. **        The 'Qt.qt_remap' vector gets reset and left in an
  258. **            undefined state.
  259. **
  260. **    Trace Flags:
  261. **        72
  262. */
  263.  
  264. mergevar(a, b, root)
  265. register int    a;
  266. register int    b;
  267. QTREE        *root;
  268. {
  269.     register int    i;
  270.  
  271. #    ifdef xQTR1
  272.     if (tTf(72, 0))
  273.     {
  274.         printf("\nmergevar(%d->%d)", a, b);
  275.         treepr(root);
  276.     }
  277. #    endif
  278.  
  279.     /*
  280.     **  Insure that 'a' and 'b' are consistant, that is,
  281.     **  that they both are in range, are defined, and range over
  282.     **  the same relation.
  283.     */
  284.  
  285.     if (a < 0 || b < 0 || a >= MAXVAR + 1 || b >= MAXVAR + 1)
  286.         syserr("mergevar: range %d %d", a, b);
  287.     if (Qt.qt_rangev[a].rngvdesc == NULL || Qt.qt_rangev[b].rngvdesc == NULL)
  288.         syserr("mergevar: undef %d %d", a, b);
  289.     if (!bequal(Qt.qt_rangev[a].rngvdesc->reldum.relid,
  290.             Qt.qt_rangev[b].rngvdesc->reldum.relid, MAXNAME) ||
  291.         !bequal(Qt.qt_rangev[a].rngvdesc->reldum.relowner,
  292.             Qt.qt_rangev[b].rngvdesc->reldum.relowner, 2))
  293.     {
  294.         syserr("mergevar: incon %.14s %.14s",
  295.             Qt.qt_rangev[a].rngvdesc->reldum.relid,
  296.             Qt.qt_rangev[b].rngvdesc->reldum.relid);
  297.     }
  298.     
  299.     /*
  300.     **  To do the actual mapping, we will set up 'Qt.qt_remap' and
  301.     **  call 'mapvars()'.  This is because I am too lazy to
  302.     **  do it myself.
  303.     */
  304.  
  305.     for (i = 0; i < MAXRANGE; i++)
  306.         Qt.qt_remap[i] = i;
  307.     Qt.qt_remap[a] = b;
  308.     mapvars(root);
  309.  
  310.     /* delete a from the range table */
  311.     declare(a, NULL);
  312. }
  313. /*
  314. **  MAKEZERO -- make a node with value 'zero'
  315. **
  316. **    A node is created with value representing the zero value
  317. **    for the specified type, that is, 0 for integers, 0.0 for
  318. **    floats, and the blank string for chars.
  319. **
  320. **    Parameters:
  321. **        typ -- the node type.
  322. **
  323. **    Returns:
  324. **        a pointer to the zero node.
  325. **
  326. **    Side Effects:
  327. **        space is grabbed from Qbuf
  328. */
  329.  
  330. QTREE *
  331. makezero(typ)
  332. int    typ;
  333. {
  334.     register int        l;
  335.     register QTREE        *s;
  336.     int            symbuf[(sizeof *s) / sizeof l];    /*word aligned*/
  337.     extern char        *need();
  338.  
  339.     s = (QTREE *) symbuf;
  340.     s->sym.type = typ;
  341.  
  342.     switch (typ)
  343.     {
  344.       case INT:
  345.         s->sym.len = l = 2;
  346.         s->sym.value.sym_data.i2type = 0;
  347.         break;
  348.  
  349.       case FLOAT:
  350.         s->sym.len = l = 4;
  351.         s->sym.value.sym_data.f4type = 0.0;
  352.         break;
  353.  
  354.       case CHAR:
  355.         s->sym.len = l = 2;
  356.         s->sym.value.sym_data.i2type = '  ';    /* (two spaces) */
  357.         break;
  358.  
  359.       default:
  360.         syserr("makezero: typ %d", typ);
  361.     }
  362.  
  363.     /* duplicate the node into Qbuf */
  364.     l += 2 + 2 * QT_HDR_SIZ;    /* size of type + len + left + right */
  365.     s = (QTREE *) need(Qbuf, l);
  366.     bmove(symbuf, s, l);
  367.     return (s);
  368. }
  369.